﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace TheFinalCountDown.UI
{
	public partial class MainForm : Form
	{
		private String UserSettingsFilePath;

		private delegate String FormatTimeFunction(TimeSpan timeLeft);

		private CountDown countDown;
		private Timer countDownTimer;

		private String formatFunctionName;
		private FormatTimeFunction formatFunction;
		private Dictionary<String, FormatTimeFunction> availableFormatFunctions;
		

		public MainForm()
		{
			InitializeComponent();

			availableFormatFunctions = new Dictionary<string, FormatTimeFunction>();
			availableFormatFunctions.Add("FullFormat", FullFormat);
			availableFormatFunctions.Add("SecondsFormat", SecondsFormat);
			availableFormatFunctions.Add("HoursFormat", HoursFormat);
			
			UserSettingsFilePath = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\TheFinalCountdown";

			countDown = new CountDown(UserSettings.Instance.TargetDate);

			LoadUserSettings();
						
			countDownTimer = new Timer();
			countDownTimer.Interval = 1000 / 60;
			countDownTimer.Tick += delegate(object sender, EventArgs e) { Update(); };

			InitiateCountDown();
		}

		private void InitiateCountDown()
		{
			countDownTimer.Start();
		}

		private new void Update()
		{
			countDown.Update();
			timeLeftTxt.Text = formatFunction(countDown.TimeLeft);
		}

		private void SelectFormatFunction(String name)
		{
			formatFunctionName = name;
			formatFunction = availableFormatFunctions[formatFunctionName];

			foreach (ToolStripMenuItem menuItem in viewToolStripMenuItem.DropDownItems)
				menuItem.Checked = menuItem.Tag.Equals(formatFunctionName);
		}

		#region Forms

		public void OnTrayIconClick(object sender, MouseEventArgs e)
		{
			trayIcon.BalloonTipTitle = "The Final Countdown";
			trayIcon.BalloonTipText = formatFunction(countDown.TimeLeft);
			trayIcon.ShowBalloonTip(1500);
		}

		private void OnTrayIconDoubleClick(object sender, MouseEventArgs e)
		{
			trayIcon.Visible = false;
			Show();
			WindowState = FormWindowState.Normal;
		}

		public void OnSettings(object sender, EventArgs e)
		{
			SettingsForm settingsForm = new SettingsForm();
			settingsForm.Show();
		}

		public void OnChangeFormatFunction(object sender, EventArgs e)
		{
			ToolStripMenuItem selectedMenuItem = (sender as ToolStripMenuItem);
			String formatFunctionName = selectedMenuItem.Tag as String;
			SelectFormatFunction(formatFunctionName);
		}

		public void OnExit(object sender, EventArgs e)
		{
			SaveUserSettings();
			Application.Exit();
		}

		public void OnAbout(object sender, EventArgs e)
		{
			AboutForm aboutForm = new AboutForm();
			aboutForm.Show();
		}

		public void OnResize(object sender, EventArgs e)
		{
			switch (WindowState)
			{
				case FormWindowState.Minimized:
					Hide();
					trayIcon.Visible = true;
					break;
			}
		}

		#endregion

		#region User Settings

		private void LoadUserSettings()
		{
			UserSettings.Load(UserSettingsFilePath);

			SelectFormatFunction(UserSettings.Instance.FormatFunctionName);
			countDown.TargetDate = UserSettings.Instance.TargetDate;
		}

		private void SaveUserSettings()
		{
			UserSettings.Instance.FormatFunctionName = formatFunctionName;
			UserSettings.Instance.TargetDate = countDown.TargetDate;

			UserSettings.Save(UserSettingsFilePath);
		}

		#endregion

		#region Format Functions

		private String FullFormat(TimeSpan timeLeft)
		{
			return String.Format("{0:00}:{1:00}:{2:00}:{3:00}:{4:00}",
								 timeLeft.Days,
								 timeLeft.Hours,
								 timeLeft.Minutes,
								 timeLeft.Seconds,
								 timeLeft.Milliseconds > 99 ? timeLeft.Milliseconds / 10 : timeLeft.Milliseconds);
		}

		private String SecondsFormat(TimeSpan timeLeft)
		{
			return String.Format("{0:00000000000000}", timeLeft.TotalSeconds);
		}

		private String HoursFormat(TimeSpan timeLeft)
		{
			return String.Format("{0:00000000000000}", timeLeft.TotalHours);
		}

		#endregion

		#region Get and Set

		public CountDown CountDown
		{
			get { return countDown; }
		}

		#endregion
	}
}
